#include <iostream> 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/opencv.hpp>

#include "hand_tracking_api.h"

using namespace cv;
using namespace std;


std::string GetGestureResult(int result)
{
	std::string result_str = "Unknown";
	switch (result)
	{
	case 1:
		result_str = "One";
		break;
	case 2:
		result_str = "Two";
		break;
	case 3:
		result_str = "Three";
		break;
	case 4:
		result_str = "Four";
		break;
	case 5:
		result_str = "Five";
		break;
	case 6:
		result_str = "Six";
		break;
	case 7:
		result_str = "ThumbUp";
		break;
	case 8:
		result_str = "Ok";
		break;
	case 9:
		result_str = "Fist";
		break;

	default:
		break;
	}

	return result_str;
}

std::string GetHandUpHandDownResult(int result)
{
	std::string result_str = "Unknown֪";
	switch (result)
	{
	case -1:
		result_str = "Unknown֪֪";
		break;
	case 1:
		result_str = "Up";
		break;
	case 2:
		result_str = "Down";
		break;

	default:
		break;
	}

	return result_str;
}

void LandmarksCallBackImpl(int image_index, HandLandMarks* infos, int count)
{
	std::cout << "image_index: " << image_index << std::endl;
	std::cout << "hand joint num: " << count << std::endl;
	for (int i = 0; i < count; ++i)
	{
		std::cout << "x=" << infos[i].x << ",  y=" << infos[i].y << ", z=" << infos[i].z << endl;
	}
}

void GestureResultCallBackImpl(int image_index, int* recogn_result, int count)
{
	std::cout << "image_index:" << image_index << std::endl;
	for (int i = 0; i < count; ++i)
	{
		std::cout << "No." << i << "ֻhand is recognized as " << GetGestureResult(recogn_result[i]) <<std::endl;
	}
}


int main()
{

	/* Mediapipe Hand Tracking */
	std::string mediapipe_hand_tracking_model_path = "./hand_tracking_desktop_live.pbtxt";
	
	if (MediapipeHandTrackingInit(mediapipe_hand_tracking_model_path.c_str()))
	{
		std::cout << "Mediapipe_Hand_Tracking_Init success." << std::endl;
	}
	else
	{
		std::cout << "Mediapipe_Hand_Tracking_Init fail." << std::endl;
	}

	// Regitster Callback function
	if (MediapipeHandTrackingReigeterLandmarksCallback(LandmarksCallBackImpl))
	{
		std::cout << "Register Landmarks success." << std::endl;
	}
	else
	{
		std::cout << "Register Landmarks fail." << std::endl;
	}

	if (MediapipeHandTrackingRegisterGestureResultCallback(GestureResultCallBackImpl))
	{
		std::cout << "Register Gesture Result success." << std::endl;
	}
	else
	{
		std::cout << "Register Gesture Resul fail." << std::endl;
	}

	/* 1 第一种方式：传入视频路径识别视频中的手势 */
	MediapipeHandTrackingDetectVideo(0);

#if 0
	// Open first camera
	VideoCapture cap(0);
	// Check the camera is open or not
	if (!cap.isOpened())
	{
		cout << "Open Camera error!" << endl;
	}

	// Create Video Window
	namedWindow("Open Camera", 1);

	int image_index = 0;
	while (1)
	{
		// Create Mat Object
		Mat frame;
		// Read a frame from cap
		bool res = cap.read(frame);
		if (!res)
		{
			break;
		}

		// if read fail
		if (frame.empty())
		{
			break;
		}

		Mat copyMat;
		frame.copyTo(copyMat);

		/*Mat copyMat;
		copyMat = frame;*/

		uchar* pImageData = copyMat.data;


		/* 2 第二种方式：传入视频帧并通过回调函数回调结果 */
		if (MediapipeHandTrackingDetectFrame(image_index, copyMat.cols, copyMat.rows, (void*)pImageData))
		{
			std::cout << "Mediapipe_Hand_Tracking_Detect_Frame success." << std::endl;
		}
		else
		{
			std::cout << "Mediapipe_Hand_Tracking_Detect_Frame fail." << std::endl;
		}

		/* 3 第三种方式：传入视频帧直接返回手势识别结果，不通过回调函数返回结果 */
		// GestureRecognitionResult gestureRecognitionResult = { {-1, -1}, {-1, -1}};
		// if (MediapipeHandTrackingDetectFrameDirect(copyMat.cols, copyMat.rows, (void*)pImageData, gestureRecognitionResult))
		// {
		// 	for (int i = 0; i < 2; ++i)
		// 	{
		// 		if (gestureRecognitionResult.m_Gesture_Recognition_Result[i] != -1)
		// 		{
		// 			std::cout << "No. " << i << "ֻis recognized as " << GetGestureResult(gestureRecognitionResult.m_Gesture_Recognition_Result[i]) << std::endl;
		// 		}

		// 		if (gestureRecognitionResult.m_HandUp_HandDown_Detect_Result[i] != -1)
		// 		{
		// 			std::cout << "No. " << i << "ֻis recognized as " << GetHandUpHandDownResult(gestureRecognitionResult.m_HandUp_HandDown_Detect_Result[i]) << std::endl;
		// 		}
		// 	}

		// }
		// else
		// {
		// 	std::cout << "Mediapipe_Hand_Tracking_Detect_Frame_Direct fail." << std::endl;
		// }


		// Show the picture which captured from camera.
		imshow("Open Camera", frame);
		// Exit if key pressed
		if (waitKey(1) >= 0)
		{
			break;
		}

		image_index += 1;
	}

	cap.release();
	cv::destroyAllWindows();

#endif

	getchar();

	if (MediapipeHandTrackingRelease())
	{
		std::cout << "Mediapipe Release success." << std::endl;
	}
	else
	{
		std::cout << "Mediapipe Release fail." << std::endl;
	}

	return 0;
}